module gorevli; //görevli

// Puanları sayacak. Puanları oyuncuya aktaracak. Oyuncuya kart çektirecek...
import kart;
// dört tane oyun kartı alır. Aldığı 4 Oyun kartının dizisini döndürür
// ve bu 4 oyun kartını OyunKartı referans dizisinden çıkarır.
OyunKartı[] dörtOyunKartıAl(ref OyunKartı[] kartlar)
in
{
    assert(kartlar.length >= 4);
}
out (sonuç)
{
    assert(sonuç.length == 4);

    /*
     * Burada, kartlar parametresinin uzunluğunun dört azaldığını da
     * denetlemek isterdik; ama D, in ve out blokları arasında iletişim
     * sağlamıyor. O yüzden eski uzunluğu in bloğunda saklayıp out
     * bloğundaki bir karşılaştırmada kullanamıyoruz.
     */
}
body
{
    OyunKartı[] atılacakKartlar=kartlar[0..4].dup;
    kartlar = kartlar[4..$];
    return atılacakKartlar;
}
unittest
{
    auto kart = yeniDeste();
    auto kart2 = kart.dup;
    auto kart3 = dörtOyunKartıAl(kart);
    assert(kart2[0..4]==kart3);
    assert(kart2[4..$]==kart);
}

/*
 * birOyuncuKartıAl verilen kart listesinden numara ile seçilen kart listesini değer olarak döndürür 
 * ve ayrıca döndürülen kartı seçilen kart listesinden çıkartır.
 * DİKKAT seçilenKart kartlar listesinde 0'dan değil 1'den sayılmaya başlanır.
 * 
 * */

OyunKartı birOyunKartıAl(ref OyunKartı[] kartlar, int seçilenKart) //seçilen kart genelde 4 taneden seçer. DİKKAT: seçilen kart 0dan değil 1'den başlar.
in
{
    assert(kartlar.length >= 1);
    assert(kartlar.length <= seçilenKart);
}

body
{
    OyunKartı atılacakKart = kartlar[seçilenKart];
    
    kartlar = kartlar[0..seçilenKart]~kartlar[seçilenKart..$];
    return atılacakKart;
}




/*
 * Büyük ihtimalle kart puanları tutulmak istendi.
 */
 
 /*
  * Şuan sadece oyuncudaki kartlar tutulmak isteniyor.
  * Oyundaki kartlar tutulup en çok kim kart almış ve kartların puanlarını  tutmada yararlı.
  * */
 
 
struct birEldekiHerşey  /// Bir elde tutulması gereken Puanlar Kartlar
{
    OyunKartı[] birinciOyuncudakiKartlar; //Birinci Oyuncu kullanıcı
    OyunKartı[] ikinciOyuncudakiKartlar;  //Bilgisayar Kullanıcısı
    OyunKartı[] üçüncüOyuncudakiKartlar; //Denden 
    OyunKartı[] dördüncüOyuncudakiKartlar;//Denden     
}


/*
struct tümEl
{
    /// birinciOyuncudakiTümKartlarınDeğeri
    DesteDeğer[OyunKartı] bOTKD;
    DesteDeğer[OyunKartı] iOTKD;
    DesteDeğer[OyunKartı] üOTKD;
    DesteDeğer[OyunKartı] dOTKD;
    

}

*/
struct birEldekiPuan  /// Bir elde tutulması gereken Puanlar Kartlar
{
    int birinciOyuncudakiKartlar;
    int ikinciOyuncudakiKartlar;
    int üçüncüOyuncudakiKartlar;
    int dördüncüOyuncudakiKartlar;
    
}

struct tümEldekiPuan
{
    /// birinciOyuncudakiTümKartlarınDeğeri
    int bOTKD;
    int iOTKD;
    int üOTKD;
    int dOTKD;
    
    int enYüksekPuanıSırala(int a, int b, int c, int d)
    {
        int en = a > b ? a : b;
        en = en > c ? en : c;
        en = en > d ? en : d;
        return en;
    }
    
    @property int enYüksek()
    {
        return enYüksekPuanıSırala(bOTKD,iOTKD,üOTKD,dOTKD);
    }

}





// true ise alır false ise alamaz
bool alır_mı(OyunKartı atılan, OyunKartı yerdeki)
{
    return (atılan.değer == yerdeki.değer) || (atılan.değer == 'J');
}
unittest 
{ //♠♡♢♣
    auto a1 = OyunKartı('4','♠');
    auto a2 = OyunKartı('5','♠');
    
    auto a3 = OyunKartı('4','♣');
    auto a4 = OyunKartı('4','♠');
    
    auto a5 = OyunKartı('J','♢');
    auto a6 = OyunKartı('5','♠');
    assert(!alır_mı(a1,a2));
    
    assert(alır_mı(a3,a4));
    
    assert(alır_mı(a5,a6));


}
